package com.richfun.boot.common.config;

import java.security.MessageDigest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.richfun.boot.common.exception.SysException;
import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

/**
 * JWT类
 * @author geYang  2018-05-18
 */
public class JWT {
    private static Logger logger = LoggerFactory.getLogger(JWT.class);
    /**
     * JWT过滤后request中存放用户信息的参数名
     * */
    public static final String USER_KEY = "userId";
    /**
     * 凭证key
     */
    final static String JWT_KEY = "token";
    /**
     * 加密秘钥
     */
    private static final String JWT_SECRET = "aHR0cHM6Ly9teS5vc2NoaW5hLm5ldC91LzM2ODE4Njg=";
    /**
     * 有效时间(小时)
     */
    private static final int JWT_EXPIRE = 12;

    /**
     * 生成Token签名
     * @param userId 用户ID
     * @return 签名字符串
     */
    public static Map<String,Object> generateTokenMap(long userId) {
        Date nowDate = new Date();
        Date expireDate = getExpireDate();
        String token = Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setSubject(String.valueOf(userId))
                .setIssuedAt(nowDate)
                .setExpiration(expireDate)
                .signWith(SignatureAlgorithm.HS512, JWT_SECRET)
                .compact();
        Map<String,Object> tokenMap = new HashMap<>();
        tokenMap.put("token", token);
        tokenMap.put("expireTime", expireDate);
        return tokenMap;
    }
    
    /**
     * 获取过期时间
     * @author geYang
     * */
    private static Date getExpireDate() {
        return new Date(System.currentTimeMillis() + JWT_EXPIRE * 3600000);
    }

    /**
     * 获取签名信息
     */
    public static Claims getClaimByToken(String token) {
        try {
            return Jwts.parser().setSigningKey(JWT_SECRET).parseClaimsJws(token).getBody();
        } catch (Exception e) {
            logger.debug("JWT TOKEN 校验失败", e);
            return null;
        }
    }

    /**
     * 判断Token是否过期
     */
    public static boolean isTokenExpired(Date expiration) {
        return expiration.before(new Date());
    }
    
    /**
     * SHA-256 密码加密
     * @param password 未加密密码
     * @return String 加密后密码
     * @author geYang
     * */
    public static String SHA256(String password) {
        try {
            byte[] bytes = password.getBytes("UTF-8");
            byte[] digest = MessageDigest.getInstance("SHA-256").digest(bytes);
            return new String(encodeHex(digest));
        } catch (Exception e) {
            e.printStackTrace();
            throw new SysException("系统加密处理异常");
        }
    }

    /**
     * 转16进制
     * */
    private static char[] encodeHex(final byte[] data) {
        final int l = data.length;
        final char[] out = new char[l << 1];
        for (int i = 0, j = 0; i < l; i++) {
            out[j++] = DIGITS_LOWER[(0xF0 & data[i]) >>> 4];
            out[j++] = DIGITS_LOWER[0x0F & data[i]];
        }
        return out;
    }
    private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

}
